package com.c6906.vdam.das.service;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.c6906.vdam.das.config.redis.RedisUtils;
import com.c6906.vdam.das.model.entity.TerminalBusinessInfo;
import com.c6906.vdam.das.model.entity.TerminalData;
import com.c6906.vdam.das.model.entity.VehiclesParkingData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

@Service
public class VehicleStatusService {
    private static final Logger logger = LoggerFactory.getLogger(VehicleStatusService.class);
    private final RedisUtils redisUtil;

    @Resource
    VehiclesParkingDataService vehiclesParkingDataService;
    @Resource
    GeoLocationService geoLocationService;

    public VehicleStatusService(RedisUtils redisUtil) {
        this.redisUtil = redisUtil;
    }

    /**
     * 接收车辆状态上报
     *
     * @param vehicleCode 车辆ID
     * @param ignited     是否点火 (true: 点火, false: 熄火)
     */
    public void onVehicleStatusReport(String vehicleCode, String ignited, TerminalData terminalData) {
        String statusKey = "vehicle:" + vehicleCode + ":status";

        if (redisUtil.exists(statusKey)) {
            String currentStatus = redisUtil.get(statusKey).toString();
            if (!currentStatus.equals(ignited)) {
                String shutdownKey = "vehicle:" + vehicleCode + ":shutdown";
                if (ignited.equals("0")) {
                    // 车辆开始熄火时，记录标记，并设置过期时间为3分钟的 shutdownKey
                    redisUtil.setExpire(shutdownKey, "", 3, TimeUnit.MINUTES);
                    // 保存 terminalData 到一个单独的 key 供过期事件时使用
                    String shutdownDataKey = "vehicle:" + vehicleCode + ":shutdown:terminalData";
                    redisUtil.set(shutdownDataKey, JSONUtil.toJsonStr(terminalData));
                    logger.info("车辆[{}]熄火", vehicleCode);
                } else {
                    // 车辆重新点火时，取消熄火标记及清理保存的 terminalData
                    String shutdownDataKey = "vehicle:" + vehicleCode + ":shutdown:terminalData";
                    redisUtil.delete(shutdownKey);
                    redisUtil.delete(shutdownDataKey);
                    // 结束停车记录，更新时长等
                    VehiclesParkingData vehiclesParkingData = vehiclesParkingDataService.getLatestTripData(vehicleCode);
                    if (vehiclesParkingData != null) {
                        logger.info("车辆[{}]重新点火", vehicleCode);
                        vehiclesParkingData.setEndTime(DateUtil.parse(terminalData.getTerminalTime()));
                        vehiclesParkingData.setDuration(DateUtil.between(vehiclesParkingData.getStartTime(), vehiclesParkingData.getEndTime(), DateUnit.MINUTE));
                        vehiclesParkingData.setUpdateTime(DateUtil.date());
                        vehiclesParkingDataService.updateById(vehiclesParkingData);
                    }
                }
                // 更新车辆状态
                redisUtil.set(statusKey, ignited);
            }
        } else {
            // 设置车辆状态
            redisUtil.set(statusKey, ignited);
        }
    }

    /**
     * 处理 Redis 过期事件，该方法应由 Redis keyspace 通知调用，确保 Redis 已启用过期事件通知
     * 当 key 格式为 vehicle:{vehicleCode}:shutdown 过期时，检查车辆状态并执行后续处理
     */
    public void onRedisExpired(String expiredKey) {
        if (expiredKey != null && expiredKey.endsWith(":shutdown")) {
            // key 格式为 vehicle:{vehicleCode}:shutdown
            String[] parts = expiredKey.split(":");
            if (parts.length >= 3) {
                String vehicleCode = parts[1];
                String statusKey = "vehicle:" + vehicleCode + ":status";
                if (redisUtil.exists(statusKey) && "0".equals(redisUtil.get(statusKey))) {
                    String dataKey = "vehicle:" + vehicleCode + ":shutdown:terminalData";
                    Object terminalDataJson = redisUtil.get(dataKey);
                    if (terminalDataJson != null) {
                        TerminalData terminalData = JSONUtil.toBean(terminalDataJson.toString(), TerminalData.class);
                        handleAfterShutdown(vehicleCode, terminalData);
                        redisUtil.delete(dataKey);
                    }
                }
            }
        }
    }

    /**
     * 车辆熄火3分钟后的业务逻辑 (如告警、记录等)
     */
    private void handleAfterShutdown(String vehicleCode, TerminalData terminalData) {
        // 触发停车状态后的操作（如告警、记录日志等）
        logger.info("车辆[{}] 已停车", vehicleCode);
        TerminalBusinessInfo terminalBusinessInfo = redisUtil.terminalInfoIsExistFormRedis("SN" + terminalData.getTerminalSn());
        VehiclesParkingData vehiclesParkingData = new VehiclesParkingData(terminalData, terminalBusinessInfo);
        try {
            String result = geoLocationService.getLocation(vehiclesParkingData.getLatitude(), vehiclesParkingData.getLongitude());
            JSONObject resultObject = JSONUtil.parseObj(result);
            if (resultObject.getInt("status") == 0) {
                vehiclesParkingData.setPoiName(resultObject.getJSONObject("result").getStr("formatted_address_poi"));
                JSONArray poiRegions = resultObject.getJSONObject("result").getJSONArray("poiRegions");
                if (poiRegions != null) {
                    for (Object poiRegion : poiRegions) {
                        JSONObject poiRegionObject = (JSONObject) poiRegion;
                        if (poiRegionObject.getStr("direction_desc").equals("内")) {
                            vehiclesParkingData.setPoiTag(poiRegionObject.getStr("tag"));
                        }
                    }
                }
            }
            vehiclesParkingData.setApiResult(result);
        } catch (Exception e) {
            logger.error("获取位置信息失败", e);
        }
        vehiclesParkingDataService.save(vehiclesParkingData);
    }
}